import sys
from PyQt6.QtWidgets import QApplication
from PyQt6.QtWidgets import QDialog, QMenu,QMessageBox
from PyQt6.QtGui import QShortcut, QKeySequence

from pyproj import Geod
import math

from sls_TOOLSDialog import Ui_TOOLSDialog

class TOOLSDialog(QDialog):
    def __init__(self, parent, menu:QMenu):
        super().__init__(parent)
        self.parent = parent
        self.menu = menu
        self.parent.ui.uavPathPlan.setEnabled(False)
        self.parent.ui.ugvPathPlan.setEnabled(False)
        self.parent.ui.tools.setEnabled(False)
        # 初始化UI
        self.ui = Ui_TOOLSDialog()
        self.ui.setupUi(self)
        self.setWindowTitle(f"空地协同工具栏")
        
        self.click_points = []
        self.path_points  = []
        self.marker_name  = []
        self.clicknum     = 0
        
        self.ui.menu.itemClicked.connect(self.on_menu_item_clicked)
        self.ui.coordinate.itemClicked.connect(self.on_coordinate_item_clicked)
        self.parent.notifyClass.add_notify_Cordinate(self.on_click_point)
        self.ui.Btn_Marker.clicked.connect(self.add_CustomMarker_Clicked)
        self.undo_shortcut = QShortcut(QKeySequence("Ctrl+Z"), parent)
        self.undo_shortcut.activated.connect(self.remove_point)
        
        self.status_stylesheet_info = "color: #ffffff; background-color: #007bff; border: 1px solid #0056b3; border-radius: 4px; padding: 4px 8px; font-weight: bold;"
        self.status_stylesheet_warn = "color: #212529; background-color: #ffc107; border: 1px solid #e0a800; border-radius: 4px; padding: 4px 8px; font-weight: bold;"
        self.status_stylesheet_calc = "color: #ffffff; background-color: #28a745; border: 1px solid #1e7e34; border-radius: 4px; padding: 4px 8px; font-weight: bold;"
        
        self.clearallset()
        
    def on_menu_item_clicked(self, item):
        """选择菜单模式"""
        self.clearallset()
        menu_text = item.text()
        self.ui.label_status.setStyleSheet(self.status_stylesheet_info)
        # 根据菜单文本执行不同操作
        if "距离测量" in menu_text:
            self.ui.label_status.setText("📏 请选择两个点进行距离测量")
        elif "角度计算" in menu_text:
            self.ui.label_status.setText("📐 请选择三个点进行角度计算")
        elif "NE 位置" in menu_text:
            self.ui.label_status.setText("🧭 请选择两个点进行 NE 计算")
        elif "无限模式" in menu_text:
            self.ui.label_status.setText("✨ 当前模式可无限制点")
        else:
            pass
    
    def on_coordinate_item_clicked(self, item):
        '''点击文本复制坐标'''
        if not self.ui.menu.selectedItems():
            return
        for i in range(self.ui.coordinate.count()):
            current_item = self.ui.coordinate.item(i)
            current_text = current_item.text()
            if ' 📑' in current_text:
                current_item.setText(current_text.replace(' 📑', ''))

        original_text = item.text().replace(' 📑', '')
        parts = original_text.split()
        coord_text = ' '.join(parts[-2:])
        QApplication.clipboard().setText(coord_text)
        
        item.setText(original_text + ' 📑')

    def add_CustomMarker_Clicked(self):
        '''添加自定义坐标点'''
        if not self.ui.menu.selectedItems():
            QMessageBox.warning(self, "提示", "请先选择模式")
            return
        if self.showwarning():
            return

        input_text = self.ui.latitude_longitude.text().strip()
        
        if not input_text:
            QMessageBox.warning(self, "输入错误", "请输入经纬度\nPlease enter coordinates")
            return
        
        # 支持多种分隔符：中文逗号、英文逗号、空格
        separators = ['，', ',', ' ']
        separator_found = None
        
        for sep in separators:
            if sep in input_text:
                separator_found = sep
                break
        
        if separator_found is None:
            QMessageBox.warning(self, "输入错误", "请输入正确的经纬度格式：纬度,经度\n")
            return
            
        try:
            parts = input_text.split(separator_found)
            parts = [part.strip() for part in parts if part.strip()]
            if len(parts) != 2:
                QMessageBox.warning(self, "输入错误", "请输入正确的经纬度格式：纬度,经度\n")
                return
            latitude,longitude = float(parts[0]),float(parts[1])
            
            if not (-90 <= latitude <= 90):
                QMessageBox.warning(self, "输入错误", "纬度范围应在-90到90之间\n")
                return
            if not (-180 <= longitude <= 180):
                QMessageBox.warning(self, "输入错误", "经度范围应在-180到180之间\n")
                return
                
            self.append_point(latitude, longitude)
            self.ui.latitude_longitude.clear()
            
        except ValueError:
            QMessageBox.warning(self, "输入错误", "请输入有效的数字\n")
        except Exception as e:
            QMessageBox.warning(self, "错误", f"处理坐标时发生错误：{str(e)}\n")

    def on_click_point(self,latitude,longitude):
        '''地图点击添加坐标点'''
        if not self.ui.menu.selectedItems():
            QMessageBox.warning(self, "提示", "请先选择模式")
            return
        if self.showwarning():
            return
        self.append_point(latitude,longitude)     

    def append_point(self,latitude,longitude):
        '''添加坐标点实现'''
        self.click_points.append([latitude,longitude])
        self.marker_name.append(f"path_point*{len(self.click_points)}" )
        self.parent.add_marker(latitude, longitude,f"path_point*{len(self.click_points)}")
        path_points = [[point[1], point[0]] for point in self.click_points]
        self.path_points = [[point[1], point[0]] for point in self.click_points]
        color = "#E20D29"
        self.parent.del_polyline("planed_path")
        self.parent.add_polyline(path_points,color,"planed_path")
        self.clicknum = self.clicknum + 1
        
        self.showstatus()
        if self.clicknum <= 9:
            self.ui.coordinate.addItem(f"{self.clicknum}\uFE0F\u20E3 {latitude:.8f}, {longitude:.8f}")
        elif self.clicknum > 9:
            self.ui.coordinate.addItem(f"{self.clicknum // 10}\uFE0F\u20E3{self.clicknum % 10}\uFE0F\u20E3 {latitude:.8f}, {longitude:.8f}")
        else:
            self.ui.coordinate.addItem(f"{self.clicknum}. {latitude:.8f}, {longitude:.8f}")

    def showstatus(self):
        '''根据当前点击点数显示状态'''
        self.ui.label_status.setStyleSheet(self.status_stylesheet_info)
        geod = Geod(ellps="WGS84")
        if "距离测量" in self.ui.menu.selectedItems()[0].text():
            if self.clicknum == 0:
                self.ui.label_status.setText("📏 请选择两个点进行距离测量")
            elif self.clicknum == 1:
                self.ui.label_status.setText("📏 请再标记1个点")
            elif self.clicknum == 2:
                # 计算距离
                lon1, lat1 = self.click_points[0][1], self.click_points[0][0]
                lon2, lat2 = self.click_points[1][1], self.click_points[1][0]
                az12, az21, dist = geod.inv(lon1, lat1, lon2, lat2)
                self.ui.label_status.setStyleSheet(self.status_stylesheet_calc)
                self.ui.label_status.setText(f"📏 两点距离: {abs(dist):.2f}米 ({abs(dist)/1000:.3f}千米)")
        
        if "角度计算" in self.ui.menu.selectedItems()[0].text():
            if self.clicknum == 0:
                self.ui.label_status.setText("📐 请选择三个点进行角度计算")
            elif self.clicknum == 1:
                self.ui.label_status.setText("📐 请再标记2个点")
            elif self.clicknum == 2:
                self.ui.label_status.setText("📐 请再标记1个点")
            elif self.clicknum == 3:
                # 计算角度（点B为顶点）
                A_lon, A_lat = self.click_points[0][1], self.click_points[0][0]
                B_lon, B_lat = self.click_points[1][1], self.click_points[1][0]
                C_lon, C_lat = self.click_points[2][1], self.click_points[2][0]

                az_BA, az_AB, dist_BA = geod.inv(B_lon, B_lat, A_lon, A_lat)
                az_BC, az_CB, dist_BC = geod.inv(B_lon, B_lat, C_lon, C_lat)
                
                # 计算夹角（处理360度边界）
                angle = abs(az_BA - az_BC)
                if angle > 180:
                    angle = 360 - angle
                    
                self.ui.label_status.setStyleSheet(self.status_stylesheet_calc)
                self.ui.label_status.setText(f"📐 角度: {angle:.2f}°")
        
        if "NE 位置" in self.ui.menu.selectedItems()[0].text():
            if self.clicknum == 0:
                self.ui.label_status.setText("🧭 请选择两个点进行 NE 计算")
            elif self.clicknum == 1:
                self.ui.label_status.setText("🧭 请再标记1个点")
            elif self.clicknum == 2:
                # 计算NE相对位置
                ref_lon   , ref_lat    = self.click_points[0][1], self.click_points[0][0]
                target_lon, target_lat = self.click_points[1][1], self.click_points[1][0]
                
                # 分别计算经度方向和纬度方向的距离
                # 纬度方向距离（北南方向）
                _, _, north_dist = geod.inv(ref_lon, ref_lat, ref_lon, target_lat)
                # 经度方向距离（东西方向）  
                _, _, east_dist = geod.inv(ref_lon, ref_lat, target_lon, ref_lat)
                
                north_dir = "北" if target_lat > ref_lat else "南"
                east_dir = "东" if target_lon > ref_lon else "西"
                
                self.ui.label_status.setStyleSheet(self.status_stylesheet_calc)
                self.ui.label_status.setText(f"🧭 相对位置: {north_dir}{abs(north_dist):.1f}米, {east_dir}{abs(east_dist):.1f}米")

    def showwarning(self):
        '''当前功能下点数超出警告'''
        if "距离测量" in self.ui.menu.selectedItems()[0].text() and self.clicknum >= 2:
            self.ui.label_status.setStyleSheet(self.status_stylesheet_warn)
            self.ui.label_status.setText("距离测量只需两个点,Ctrl+Z撤回后重新选择")
            return True
        if "角度计算" in self.ui.menu.selectedItems()[0].text() and self.clicknum >= 3:
            self.ui.label_status.setStyleSheet(self.status_stylesheet_warn)
            self.ui.label_status.setText("角度测量只需三个点,Ctrl+Z撤回后重新选择")
            return True
        if "NE 位置" in self.ui.menu.selectedItems()[0].text() and self.clicknum >= 2:
            self.ui.label_status.setStyleSheet(self.status_stylesheet_warn)
            self.ui.label_status.setText("NE位置只需两个点,Ctrl+Z撤回后重新选择")
            return True
        return False
    
    def remove_point(self):
        '''撤回上一个点实现'''
        if self.click_points: 
            self.click_points.pop()
            if self.marker_name:
                name = self.marker_name.pop()
                self.parent.del_marker(name)
                path_points = [[point[1], point[0]] for point in self.click_points]
                color = "#E20D29"
                self.parent.del_polyline("planed_path")
                self.parent.add_polyline(path_points,color,"planed_path")
                self.ui.coordinate.takeItem(self.ui.coordinate.count() - 1)
                self.clicknum = self.clicknum - 1 
                self.showstatus()    
    
    def clearallset(self):
        self.parent.del_polyline("planed_path")
        self.parent.del_polyline("boundary")
        self.parent.del_sortedMarkers("boundary_point")
        self.parent.del_sortedMarkers("path_point")
        self.click_points = []
        self.path_points = []
        self.marker_name = []
        self.clicknum = 0
        self.ui.coordinate.clear()
        
    def closeEvent(self, event):
        '''当对话框关闭时，重新启用父窗口的按钮'''
        self.clearallset()
        self.parent.del_polyline("history_path")
        self.parent.del_polyline("history_boundary")
        self.parent.ui.uavPathPlan.setEnabled(True)
        self.parent.ui.ugvPathPlan.setEnabled(True)
        self.parent.ui.tools.setEnabled(True)
        self.parent.notifyClass.remove_notify_Cordinate(self.on_click_point)